package deca;

/**
 * Created by zx on 16-4-6.
 */

import java.io.Serializable;
import java.util.Arrays;

public class JavaLR {
    private static int D = 10;   // Number of dimensions
    private int N = 1000;  // Number of data points
    private final double R = 0.00007;  // Scaling factor

    static class DataPoint implements Serializable {
        DataPoint(double[] x, double y) {
            this.x = x;
            this.y = y;
        }

        double[] x;
        double y;
    }

    private DataPoint[] cache;
    private static double[] w;

    public void textFile(int dimension, int nums) {
        this.D = dimension;
        this.N = nums;

        w = new double[D];
        for (int i = 0; i < D; i++) {
            w[i] = 2 * i * 0.037 - 1;
        }
//        System.out.print("Initial w: ");
//        System.out.println(Arrays.toString(w));

        cache = new DataPoint[N];
        for (int i = 0; i < N; i++) {
            int y;
            if (i % 2 == 0)
                y = 0;
            else
                y = 1;
            double[] x = new double[D];
            for (int j = 0; j < D; j++) {
                x[j] =  i * 0.000013 + j * 0.00079 + y * R;
            }

            cache[i] = new DataPoint(x, y);
        }
    }

    public void compute(int iterations){
        for(int iter = 0; iter < iterations; iter ++) {
            double[] gradient = new double[D];
            for (int i = 0; i < N; i++) {
                double[] gradient1 = new double[D];
                DataPoint p = cache[i];
                double dot = dot(w, p.x);
                double tmp = (1 / (1 + Math.exp(-p.y * dot)) - 1) * p.y;
                for (int j = 0; j < D; j++) {
                    gradient[j] += tmp * p.x[j];
                }
            }
            for (int j = 0; j < D; j++) {
                w[j] -= gradient[j];
            }
        }
        //System.out.print("Final w: ");
        //System.out.println(Arrays.toString(w));
    }

    public static double dot(double[] a, double[] b) {
        double x = 0;
        for (int i = 0; i < D; i++) {
            x += a[i] * b[i];
        }
        return x;
    }
}
